﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Text;
using DevicesInt;

namespace SCS_350_snmp
{
    public class Scs350Worker : IDeviceInterface
    {
        private static readonly SnmpWorker Worker = new SnmpWorker();

        private static readonly List<string> IgnoreOids = new List<string>
            {
                ".1.3.6.1.4.1.21678.20.10.1.1.1"    //scaAlarmsAmplifierIndex
            };
 

        static Scs350Worker()
        {
            Worker.SetStatusOids(new List<string>
                {
                    ".1.3.6.1.4.1.21678.20.10.1.1",             //scaAlarms
                    ".1.3.6.1.4.1.21678.20.13.1",               //genMmAlarms
                    ".1.3.6.1.4.1.21678.20.14.1",               //sysAlarms
                    ".1.3.6.1.4.1.21678.20.15.1",               //macAlarms
                    ".1.3.6.1.4.1.21678.20.16.1",               //liqAlarms
                    ".1.3.6.1.4.1.21678.20.17.1",               //scsAlarms
                    ".1.3.6.1.4.1.21678.20.18.1",               //patAlarms
                });
        }

        public static string GetStatus(string ip)
        {

            /*var reader = new MibMyReader("SCREENSERVICE-MAINMETERvX14-MIB.my");
            var oids = new List<string>()
                {
                    "-- 1.3.6.1.4.1.21678.20.13.1.2",
                    "-- 1.3.6.1.4.1.21678.20.14.1.1"
                };
            var found = reader.FindDescriptions(oids);
            reader.CloseStream();*/
            
            var vars = Worker.GetStatusVariables(ip);
            if (vars[0].Count == 0)
                return "ok";
            if (vars[0][0].Id.ToString() == Errors.NO_CONNECTION_OID)
                return "err:" + ReadableErrors.NO_CONNECTION;


            var errorVars = new List<VariableWithError>();
            var st = new StringBuilder();
            foreach (var varr in vars)
            {
                if(varr == null)
                    continue;

                foreach (var variable in varr)
                {
                    //Analyze variable
                    if (IgnoreOids.Contains(GetOidHead(variable.Id.ToString())))
                    {
                        continue;
                    }

                    if (variable.Data.ToString() != "1")
                    {
                        var vwe = new VariableWithError
                            {
                                Oid = variable.Id.ToString(),
                                Data = variable.Data.ToString(),
                                OidTail = GetOidTail(variable.Id.ToString())
                            };
                        FillInfo(ref vwe);
                        errorVars.Add(vwe);
                        st.Append(Severity.ALARM + ':' + vwe + ";");
                    }
                }
            }
            if (st.Length < 1)
                st.Append("ok");
            return st.ToString();
        }

        static void FillInfo(ref VariableWithError var)
        {
            var reader = new MibMyReader("SCREENSERVICE-MAINMETERvX14-MIB.my");
            var sb = new StringBuilder(var.Oid.Length + 2);
            sb.Append("-- ");
            string oid = GetOidHead(var.Oid);
            oid = oid.Remove(0, 1);
            sb.Append(oid);
            var found = reader.FindDescription(sb.ToString());
            var.Info = found;
            reader.CloseStream();
        }

        private static string GetOidHead(string oid)
        {
            var split = oid.Split('.');
            return oid.Remove(oid.Length - split[split.Length - 1].Length - 1);
        }

        private static string GetOidTail(string oid)
        {
            var split = oid.Split('.');
            return split[split.Length - 1];
        }

        [Obfuscation(Feature = "DllExport")]
        public static string CallMethod(string func, params object[] pars)
        {
            if (!File.Exists("Resources\\Libs\\SharpSnmpLib.dll") && !File.Exists("SharpSnmpLib.dll"))
                return "err:Библиотека SharpSnmpLib.dll не найдена";
            string ret;
            switch (func)
            {
                case "getstatus":
                    try
                    {
                        ret = GetStatus(pars[0].ToString());
                        return ret;
                    }
                    catch (Exception ex)
                    {
                        if (ex is IndexOutOfRangeException)
                            return "err:" + Errors.WRONG_INPUT_DATA + Errors.ARGUMENTS_COUNT;
                        return "err:" + ex.Message;
                    }
                case "getparams":
                    try
                    {
                        ret = Getparams(pars[0].ToString());
                        return ret;
                    }
                    catch (Exception ex)
                    {
                        if (ex is IndexOutOfRangeException)
                            return "err:Неверное количество аргументов";
                        return "err:" + ex.Message;
                    }
                case "traphandle":
                    try
                    {
                        ret = TrapHandle("", new byte[0], DateTime.Now);
                        return ret;
                    }
                    catch (Exception ex)
                    {
                        if (ex is IndexOutOfRangeException)
                            return "err:Неверное количество аргументов";
                        return "err:" + ex.Message;
                    }
                case "getlog":
                    try
                    {
                        //ret = Getlog(pars[0] as string, pars[1] as string);
                        //return ret;
                        return "err:" + Errors.NOT_IMPLEMENTED;
                    }
                    catch (Exception ex)
                    {
                        if (ex is IndexOutOfRangeException)
                            return "err:" + Errors.WRONG_INPUT_DATA + Errors.ARGUMENTS_COUNT;
                        return "err:" + ex.Message;
                    }
                case "flush":
                    try
                    {
                        ret = Flush();
                        return ret;
                    }
                    catch (Exception ex)
                    {
                        return "err:" + ex.Message;
                    }
                default:
                    return "err:Такой функции не существует";
            }
        }

        private static string Flush()
        {
            return "ok";
        }

        #region Interface realization

        public DeviceControl GetController(string ip)
        {
            return new Scs350Controller();
        }

        public string Getstatus(string ip)
        {
            return GetStatus(ip);
        }

        string IDeviceInterface.Getparams(string ip)
        {
            return Getparams(ip);
        }

        public static string Getparams(string ip)
        {
            return Errors.NOT_IMPLEMENTED;
        }

        public string Getlog(string ip, string logFilePath)
        {
            return Errors.NOT_IMPLEMENTED;
        }

        string IDeviceInterface.TrapHandle(string devName, byte[] serializedTrap, DateTime date)
        {
            return TrapHandle(devName, serializedTrap, date);
        }

        public static string TrapHandle(string devName, byte[] serializedTrap, DateTime date)
        {
            return "ok";
        }

        #endregion
    }
}
